home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / COMMON.ZIP / LBM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-16  |  7.8 KB  |  316 lines

  1. /*
  2.  
  3.  
  4.   copyright 1993, Alec Russell, All rights reserved
  5.  
  6.  
  7.   read DA/DP lbm, and bbms of type PBM only
  8.  
  9.    320x200, 256 color, mode 0x13 ONLY
  10.  
  11.    I apologize for the missing function, (gmalloc/gfree/f_read),
  12.    but they are all easy to replace or write.
  13.  
  14.    The memory allocation needs to be cleaned up in this code, but
  15.    it works.
  16.  
  17.    pr2() is used to print debug stuff to a second monitor
  18.    and can be deleted.
  19.  
  20. */
  21.  
  22. #pragma inline
  23.  
  24. #include <stdio.h>
  25. #include <io.h>
  26. #include <string.h>
  27. #include <conio.h>
  28. #include <dos.h>
  29.  
  30. #define BYTE unsigned char
  31. #define ULONG unsigned long
  32. #define USHORT unsigned short
  33. typedef char far * FARPTR;
  34.  
  35.  
  36. char far *gmalloc(USHORT size, char *name);
  37. char far *gfree(char far *p, char *name);
  38. void pr2(char *s, ...);
  39.  
  40. int f_read(int handle, char far *b, USHORT len);
  41.  
  42. typedef struct
  43.    {
  44.    USHORT width, height;
  45.    BYTE far *bitmap;
  46.    }
  47. shape_t;
  48.  
  49.  
  50. typedef struct
  51.    {
  52.     USHORT w,h;
  53.     short x,y;
  54.     char nPlanes;
  55.     char masking;
  56.     char compression;
  57.     char pad1;
  58.     USHORT transparentColor;
  59.     char xAspect,yAspect;
  60.     short pageW,pageH;
  61.     }
  62. bhmd_t;
  63.  
  64.  
  65. unsigned char palette[768];
  66.  
  67. /* alter a far pointer so that the offset is zero,
  68.    handy if the data is actualy 64k long */
  69. /* ---------------------- normalize() -------------------- March 26,1993 */
  70. char far *normalize(char far *p)
  71. {
  72.  
  73.    USHORT seg,off;
  74.  
  75.     seg = FP_SEG(p);
  76.     off = FP_OFF(p);
  77.     seg += (off / 16);
  78.     off &= 0x000f;
  79.     p = MK_FP(seg,off);
  80.  
  81.    return(p);
  82. }
  83.  
  84. /* convert motorola type long int to intel type long int */
  85. long  motr2intl(long l)
  86. {
  87.     return(((l & 0xff000000L) >> 24) +
  88.            ((l & 0x00ff0000L) >> 8) +
  89.            ((l & 0x0000ff00L) << 8) +
  90.            ((l & 0x000000ffL) << 24));
  91. }
  92.  
  93. /* convert motorola type int to intel type int */
  94. short  motr2inti(short n)
  95. {
  96.     return(((n & 0xff00) >> 8) | ((n & 0x00ff) << 8));
  97. }
  98.  
  99.  
  100. /* de-compress the run-length encoded data */
  101. /* ---------------------- de_compress() ------------------ March 23,1993 */
  102. FARPTR de_compress(BYTE far *buffer, short width, short height)
  103. {
  104.    unsigned char far *buff, far *p;
  105.    short y;
  106.     USHORT c;
  107.    USHORT i, n;
  108.  
  109.    // gmalloc is the same as farmalloc()
  110.    buff=gmalloc((unsigned long)width*height, "decomp");
  111.    p=buff;
  112.  
  113.    for ( y=0; y < height; y++ )
  114.       {
  115.       n=0;
  116.       do
  117.          {
  118.          c=*buffer++;
  119.          if ( c & 0x80 )
  120.             {
  121.                i = ((~c) & 0xff) + 2;
  122.                c=*buffer++;
  123.                while ( i-- )
  124.                {
  125.                *buff++=c;
  126.                n++;
  127.                }
  128.             }
  129.          else
  130.             {
  131.                i=(c & 0xff)+1;
  132.                while ( i-- )
  133.                {
  134.                *buff++=*buffer++;
  135.                n++;
  136.                }
  137.             }
  138.          }
  139.       while ( n < width );
  140.       }
  141.  
  142.    return(p);
  143. }
  144.  
  145.  
  146. /*
  147.    read one lbm, or bbm file created with DA or DP
  148.    MAke sure the stencil, and other option are OFF when a picture
  149.    is saved. If the stencil option is one when the picture is saved, DA will
  150.    save the picture in ILBM format which is PLANED pict data, which this code
  151.    doesn't handle.
  152. */
  153. /* ---------------------- read_pbm() --------------------- March 27,1993 */
  154. short read_pbm(char *fname, shape_t *shape)
  155. {
  156.    FILE *fp;
  157.    unsigned char *p;
  158.    USHORT i, err=0;
  159.    char b[5], sub_type[5];
  160.    unsigned long l;
  161.    USHORT width, height;
  162.    bhmd_t bhmd;
  163.    unsigned char far *buffer=NULL;
  164.    char far *t1;
  165.    short skipped=0;
  166.  
  167.  
  168. pr2("Reading: %s", fname);
  169.  
  170.    fp=fopen(fname, "rb");
  171.    if ( fp )
  172.       {
  173.       fread(b, 1,4, fp);
  174.       if ( !memcmp(b, "FORM", 4) )
  175.          {
  176. pr2("Form type FORM found");
  177.            /* ignore the size */
  178.            fread((char *)&l,1,4,fp);
  179.  
  180.            /* get the subtype */
  181.            fread(sub_type, 1,4, fp);
  182.          if ( !memcmp(sub_type, "PBM ", 4) )
  183.             {
  184. pr2("sub type %4.4s", sub_type);
  185.  
  186.               /* read all the chunks */
  187.               do {
  188.                   fread(b,1,4,fp);
  189.                   fread((char *)&l,1,4,fp);
  190.                   l=motr2intl(l);
  191.                   if(l & 1L)
  192.                   ++l;
  193.  
  194.                /* HEADER */
  195.                if ( !memcmp(b, "BMHD", 4) )
  196.                   {
  197.                   if ( fread(&bhmd, 1, sizeof(bhmd_t), fp) == sizeof(bhmd_t) )
  198.                      {
  199.                      width=motr2inti(bhmd.w);
  200.                      height=motr2inti(bhmd.h);
  201. pr2("width %d height %d", width, height);
  202.                      shape->width=width;
  203.                      shape->height=height;
  204.                      }
  205.                   else
  206.                      {
  207.                      printf("ERROR reading BHMD\n");
  208.                      err=1;
  209.                      }
  210.                   }
  211.                else
  212.                   {
  213.                   /* PALETTE */
  214.                   if ( !memcmp(b, "CMAP", 4) )
  215.                      {
  216. pr2("got cmap");
  217.                      if ( l != 768 )
  218.                         {
  219.                         printf("Invalid palette\n");
  220.                         err=1;
  221.                         }
  222.                      else
  223.                         {
  224.                         fread(palette, 1, 768, fp);
  225.                         for ( p=palette, i=0; i < 768; i++, p++ )
  226.                            *p>>=2;
  227.                         }
  228.                      }
  229.                   else
  230.                      {
  231.                      /* BITMAP, may be packed */
  232.                      if ( !memcmp(b, "BODY", 4) )
  233.                         {
  234. pr2("Got body");
  235.                         // gmalloc is the same as farmalloc()
  236.                         buffer=gmalloc(64000u, "body");
  237.  
  238.                         pr2("read body");
  239.                         fseek(fp, 0l, SEEK_CUR);  // must do this to sync up the file for
  240.                                                   // the far read, must do if any freads 
  241.                                                   // done, as they buffer stuff
  242.                         // f_read() reads into a far buffer
  243.                         i=f_read(fileno(fp), buffer, (unsigned short)l);
  244.                         if ( i != l )
  245.                            {
  246.                            pr2("l %ld i %u", l, i);
  247.                            exit(1);
  248.                            }
  249.  
  250.  
  251.                         if ( bhmd.compression )
  252.                            {
  253. pr2("de-compressing");
  254.                            t1=de_compress(buffer, width, height);
  255.                            gfree(buffer, "decomp"); // same as farfree()
  256.                            buffer=t1;
  257. pr2("de-compressed");
  258.                            }
  259.  
  260.                         }
  261.                      else
  262.                         {
  263.                         /* skip unknown chunk, a very important step */
  264.                         *(b + 4)=0;
  265.                         // pr2("Skipped chunk type %s", b);
  266.                         fseek(fp,l,SEEK_CUR);
  267.                         skipped++;
  268.                         }
  269.                      }
  270.                   }
  271.                }
  272.             while ( !ferror(fp) && memcmp(b,"BODY",4) && skipped < 1024 );
  273.  
  274.             }
  275.          else
  276.             {
  277.             printf("Not Brush or Pict, sub-type\n");
  278.             if ( !memcmp(sub_type, "ILBM", 4) )
  279.                {
  280.                printf("%s\n", fname);
  281.                printf("This picture is an ILBM, make sure all\n");
  282.                printf("options, eg stencils, are OFF before saving pict.\n");
  283.                }
  284.  
  285.             err=1;
  286.             }
  287.          }
  288.       else
  289.          {
  290.          printf("Not a brush or pict form\n");
  291.          err=1;
  292.          }
  293.  
  294.  
  295.       fclose(fp);
  296.       }
  297.    else
  298.       {
  299.       printf("ERROR: opening %s\n", fname);
  300.       err=1;
  301.       }
  302.  
  303.    if ( buffer && err )
  304.       {
  305.       gfree(buffer, "body"); // same as farfree()
  306.       buffer=NULL;
  307.       }
  308.  
  309.    shape->bitmap=buffer;
  310.  
  311.    return err;
  312. }
  313.  
  314.  
  315. /* ------------------------ end of file ----------------------------- */
  316.